
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#include "./protocol.h"

int main(int argc, char **argv){
    // 检查命令行参数的数量
    if(argc < 3){
        fprintf(stderr, "Usage: ./myget /path/to/get/file /path/to/save/file\n");
        exit(0);
    }

    key_t key;
    int msgid;
    msg_path_t send_path;
    recv2send_t recv_msg;

    int fd;

    // 创建一个新文件，并打开以进行写入操作
    fd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0644);
    if(fd < 0){
        perror("open()");
        exit(1);
    }

    // 通过ftok函数获取消息队列的标识符
    key = ftok(PATHNAME, PROJID);
    if(key < 0){
        perror("ftok()");
        exit(1);
    }

    // 获取消息队列标识符
    msgid = msgget(key, 0);
    if(msgid < 0){
        perror("msgget()");
        exit(1);
    }

    // 构造要发送的路径信息
    send_path.mtype = MSG_PARH;
    strcpy(send_path.path, argv[1]);

    // 向消息队列发送路径信息
    if(msgsnd(msgid, &send_path, sizeof(send_path) - sizeof(long), 0) < 0){
        perror("msgsnd()");
        exit(1);
    }
    puts("send ok");

    int over = 0;
    int pass;
    int len;
    while(!over){
        // 从消息队列接收数据消息或空消息
        if(msgrcv(msgid, &recv_msg, sizeof(recv_msg) - sizeof(long), 0, 0) < 0){
            perror("msgrcv()");
            exit(1);
        }

        switch(recv_msg.mtype){
            case MSG_DATA:
                // 接收到数据消息，将数据写入文件
                msg_data_t temp = recv_msg.data;

                pass = 0;
                while(pass < temp.data_len){
                    len = write(fd, temp.data + pass, temp.data_len);
                    printf("len = %d, data_len = %d, pass = %d\n", len, temp.data_len, pass);
                    pass += len;
                    temp.data_len -= len;
                }   
                break;

            case MSG_EMPTY:
                // 接收到空消息，文件传输完成，退出循环
                over = 1;
                break;
        }
    }

    exit(0);
}
